package com.zhaoyd.redislock.core;

import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;

/**
 * @author zhaoyd
 * @date 2020-09-22
 */
@Component
public class SimpleRedisClient<K,V> {
    private static final String charset = "UTF-8";
    @Resource
    private RedisTemplate<K,V> redisTemplate;

    /**
     * SETNX: 已存在就不会改变键的值
     * 设置成功， return true
     * 失败，return false
     * @param key
     * @param value
     * @param liveTime 超时时间，单位秒
     * @return
     */
    public boolean setNX(final String key, final String value,final long liveTime) {
        return redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                Boolean setNX = connection.setNX(key.getBytes(), value.getBytes());
                if (setNX && liveTime > 0L){
                    connection.expire(key.getBytes(), liveTime);
                }
                return setNX;
            }
        });
    }

    /**
     * 删除key
     * @param key
     * @return
     */
    public long del(final String key) {
        return redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.del(key.getBytes());
            }
        });
    }

    /**
     * @param key
     * @return
     */
    public String get(final String key) {
        return redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                try {
                    byte[] bytes = connection.get(key.getBytes());
                    if(bytes==null){
                        return null;
                    }
                    return new String(bytes, charset);
                } catch (UnsupportedEncodingException e) {
                    // e.printStackTrace();
                }
                return StringUtils.EMPTY;
            }
        });
    }

    /**
     * @param key
     * @param value
     * @param liveTime
     */
    public boolean set(String key, String value, long liveTime) {
        try{
            return this.set(key.getBytes(), value.getBytes("utf-8"), liveTime);
        }catch(Exception e){
            return this.set(key.getBytes(), value.getBytes(), liveTime);
        }

    }
    /**
     * @param key
     * @param value
     */
    public boolean set(String key, String value) {
        return this.set(key, value, 0L);
    }

    /**
     * @param key
     * @param value
     */
    public boolean set(byte[] key, byte[] value) {
        return this.set(key, value, 0L);
    }

    /**
     * @param key
     * @param value
     * @param liveTime 存活时间(单位 秒)
     */
    public boolean set(final byte[] key, final byte[] value, final long liveTime) {
        return redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                connection.set(key, value);
                if (liveTime > 0) {
                    connection.expire(key, liveTime);
                }
                return true;
            }
        });
    }

}
